package review.system.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import review.dao.RoleDAO;
import review.dao.UserDAO;
import review.dao.UserRoleDAO;
import review.entity.Roles;
import review.entity.UserRole;
import review.entity.Users;
import review.entity.model.UserState;

@Transactional
@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDAO userDAO;
	@Autowired
	private UserRoleDAO userRoleDAO;
	@Autowired
	private RoleDAO roleDAO;

	@Override
	public Users findUserByLoginname(String name) {
		List<Users> l = userDAO.findByUsername(name);
		if (l.size() > 0) {
			return l.get(0);
		}

		return null;
	}

	@Override
	public void addUser(Users user) {
		if (!StringUtils.hasText(user.getUsername())) {
			throw new RuntimeException("用户名不能为空！");
		}
		Users userExample = new Users();
		userExample.setUsername(user.getUsername());
		Example<Users> example = Example.of(userExample);
		boolean exist = userDAO.exists(example);
		if (exist) {
			throw new RuntimeException("该用户名已经注册！");
		}
		user.setState(UserState.ENABLE.getValue());
		user.setPassword(getInitPwd());
		userDAO.save(user);
	}

	private String getInitPwd() {
		SimpleHash hash = new SimpleHash("MD5", "123456");
		return hash.toString();
	}

	@Override
	public void changePwd(String oldPwd, String newPwd) {
		Users user = getLoginUser();
		if (user != null) {
			SimpleHash hash = new SimpleHash("MD5", oldPwd);
			String pwd = hash.toString();
			if (pwd.equalsIgnoreCase(user.getPassword())) {
				if (!(StringUtils.hasLength(newPwd) && newPwd.length() >= 6)) {
					throw new RuntimeException("密码必须大于等于6位！");
				}
				hash = new SimpleHash("MD5", newPwd);
				user.setPassword(hash.toString());
				userDAO.saveAndFlush(user);
			} else {
				throw new RuntimeException("原密码错误！");
			}
		} else {
			throw new RuntimeException("请先登录！");
		}
	}

	public static Users getLoginUser() {
		if (SecurityUtils.getSubject().getPrincipal() instanceof Users) {
			return (Users) SecurityUtils.getSubject().getPrincipal();
		}
		return null;
	}

	// 获取登录的用户ID
	public Integer getLoginId() {
		Users users = getLoginUser();
		if (users == null) {
			throw new RuntimeException("当前未登录");

		} else {
			return users.getId();
		}
	}

	public List<String> findRolesByLoginUser() {
		Users user = getLoginUser();
		return findRolesByUserid(user.getId());
	}

	public List<String> findRolesByUserid(Integer userid) {
		List<UserRole> ur = userRoleDAO.findByUserid(userid);
		List<String> roles = new ArrayList<>();
		for (UserRole userRole : ur) {
			Integer id = userRole.getRoleid();
			Optional<Roles> op = roleDAO.findById(id);
			if (op.isPresent()) {
				roles.add(op.get().getName());
			}
		}
		return roles;
	}

	// 判断根据ID还是用户名
	public Users judge(Users user) {
		if (!StringUtils.hasText(user.getUsername())) {
			if (user.getId() == null) {
				throw new RuntimeException("用户名或ID为空");
			} else {
				Optional<Users> optionalUsers = userDAO.findById(user.getId());
				if (!optionalUsers.isPresent()) {
					throw new RuntimeException("ID不存在");
				}
				return optionalUsers.get();
			}
		} else {
			Users users = findUserByLoginname(user.getUsername());
			if (users == null) {
				throw new RuntimeException("用户名不存在");
			}
			return users;
		}
	}

	// 根据用户名或ID修改
	public void updateUser(Users user) {
		Users users = judge(user);
		System.out.println();
		// 部门
		if (user.getDeptid() != null) {
			users.setDeptid(user.getDeptid());
		}
		// 电话
		if (user.getMobile() != null) {
			users.setMobile(user.getMobile());
		}
		// 昵称
		if (user.getNickname() != null) {
			users.setNickname(user.getNickname());
		}
		// 头像
		if (user.getPhoto() != null) {
			users.setPhoto(user.getPhoto());
		}
		// 性别
		if (user.getSex() != null) {
			users.setSex(user.getSex());
		}
		userDAO.save(users);
	}

	// 修改本人信息
	public void updateOneself(Users users) {
		Users u = getLoginUser();
		users.setId(u.getId());
		users.setUsername(u.getUsername());
		judge(users);
	}

	// 删除用户
	public void deleteUser(Users users) {
		Users u = judge(users);
		userDAO.delete(u);
	}

	// 分页查询所有的用户
	public Page<Users> findAll(int page, int size, Users user) {
		ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues().withMatcher("username",
				ExampleMatcher.GenericPropertyMatchers.contains());
		Example<Users> example = Example.of(user, matcher);
		Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.ASC, "id"));
		return userDAO.findAll(example, pageable);
	}

	// 查询全部未被禁用的用户
	public List<Users> findAllUser(Users user) {
		user.setState(UserState.ENABLE.getValue());
		ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues().withMatcher("username",
				ExampleMatcher.GenericPropertyMatchers.contains());
		Example<Users> example = Example.of(user, matcher);
		return userDAO.findAll(example, Sort.by("username"));
	}

	// 用户绑定角色
	public void userRole(Users user, Integer[] ids) {
		Users users = judge(user);
		// 当前用户的所有角色
		List<UserRole> userRoles = userRoleDAO.findByUserid(users.getId());
		// 遍历删除全部
		for (UserRole userRole : userRoles) {
			userRoleDAO.delete(userRole);
		}
		// 遍历重新为用户绑定角色
		for (Integer id : ids) {
			Optional<Roles> optionalRoles = roleDAO.findById(id);
			// 查询到角色然后为用户绑定
			if (optionalRoles.isPresent()) {
				UserRole userRole = new UserRole();
				userRole.setUserid(user.getId());
				userRole.setRoleid(optionalRoles.get().getId());
				userRoleDAO.save(userRole);
			}
		}
	}

	// 禁用用户
	public void userForbidden(Integer[] userid) {
		for (Integer id : userid) {
			Optional<Users> usersOptional = userDAO.findById(id);
			if (usersOptional.isPresent()) {
				Users users = usersOptional.get();
				users.setState(UserState.DISABLE.getValue());
			}
		}
	}

	// 恢复用户
	public void userRecover(Integer[] userid) {
		for (Integer id : userid) {
			Optional<Users> usersOptional = userDAO.findById(id);
			if (usersOptional.isPresent()) {
				Users users = usersOptional.get();
				users.setState(UserState.ENABLE.getValue());
			}
		}
	}
}
